package com.education.service;

import com.alibaba.fastjson.util.TypeUtils;
import com.education.common.cache.EhcacheBean;
import com.education.common.model.AdminUserSession;
import com.education.common.utils.ObjectUtils;
import com.education.common.utils.Result;
import com.education.common.utils.ResultCode;
import com.education.common.utils.SpringBeanManager;
import com.education.mapper.BaseMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.ibatis.session.RowBounds;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * service 父类
 * @author Jason
 * @version 1.0.0
 * @date 2021-11-21 00:52
 */
public class BaseService<M extends BaseMapper> {

    private static final String DEFAULT_PAGE_METHOD = "queryList";

    @Autowired
    protected M mapper;

    protected RedisTemplate<String, String> redisTemplate;

    protected static final Logger logger = LoggerFactory.getLogger(EhcacheBean.class);

    public Result pagination(Map params, Class<? extends BaseMapper> mapperClass, String methodName) {
        try {
            // 默认不分页
            Integer offset = RowBounds.NO_ROW_OFFSET;
            Integer limit = RowBounds.NO_ROW_LIMIT;
            if (ObjectUtils.isNotEmpty(params.get("offset"))) {
                offset = Integer.parseInt((String) params.get("offset"));
            }
            if (ObjectUtils.isNotEmpty(params.get("limit"))) {
                limit = Integer.parseInt((String) params.get("limit"));
            }
            Page page = PageHelper.offsetPage(offset, limit);

            Object pageResult = null;
            if (ObjectUtils.isNotEmpty(mapperClass)) {
                Method method = mapperClass.getMethod(methodName, Map.class);
                BaseMapper mapperBean = SpringBeanManager.getBean(mapperClass);
                method.invoke(mapperBean, params);
            } else {
                pageResult = mapper.queryList(params);
            }
            Map resultMap = new HashMap<>(0);
            resultMap.put("total", page.getTotal());
            resultMap.put("dataList", pageResult);
            return Result.success(resultMap);
        } catch (Exception e) {
            logger.error("分页异常", e);
        }
        return Result.fail();
    }

    public Result pagination(Map params) {
        return pagination(params, null, DEFAULT_PAGE_METHOD);
    }

    /**
     * 添加或修改数据
     * @param params
     * @return
     */
    public Result saveOrUpdate(Map params) {
        Integer id = (Integer) params.get("id");
        boolean updateFlag = ObjectUtils.isNotEmpty(id);
        return this.saveOrUpdate(updateFlag, params);
    }

    /**
     * 添加或修改
     * @param updateFlag
     * @param modelBeanMap
     * @return
     */
    public Result saveOrUpdate(boolean updateFlag, Map modelBeanMap) {
        try {
            String message = "";
            if (updateFlag) {
                modelBeanMap.put("update_date", new Date());
                this.update(modelBeanMap);
                message = "修改";
            } else {
                modelBeanMap.put("create_date", new Date());
                this.save(modelBeanMap);
                message = "添加";
            }
            return Result.success(ResultCode.SUCCESS, message + "成功");
        } catch (Exception e) {
            logger.error("操作异常", e);
        }
        return Result.success(ResultCode.FAIL, "操作异常");
    }

    /**
     * 添加数据
     * @param modelMap
     * @return
     */
    public int save(Map modelMap) {
        Integer result = mapper.save(modelMap);
        Object id = modelMap.get("id");
        // 如果主键id不为空的话，直接返回主键id
        if (ObjectUtils.isNotEmpty(id)) {
            return TypeUtils.castToInt(id);
        }
        return result;
    }

    /**
     * 更新数据
     * @param modelMap
     * @return
     */
    public int update(Map modelMap) {
        return mapper.update(modelMap);
    }

    /**
     * 删除单条记录
     * @param id 记录id
     * @return
     */
    public Result deleteById(Integer id) {
        int result = mapper.deleteById(id);
        if (result > 0) {
            Result.success(ResultCode.SUCCESS, "删除成功");
        }
        return Result.fail(ResultCode.FAIL, "删除数据异常");
    }

    public Result batchDeleteByIds(List<Integer> roleIds) {
        int result = mapper.batchDeleteByIds(roleIds);
        if (result == roleIds.size()) {
            Result.success(ResultCode.SUCCESS, "批量删除成功");
        }
        return Result.fail(ResultCode.FAIL, "批量删除数据异常");
    }

    /**
     * 获取管理员用户信息
     * @return
     */
    public AdminUserSession getAdminUserSession() {
        Subject subject = SecurityUtils.getSubject();
        AdminUserSession userSession = (AdminUserSession) subject.getPrincipal();
        if (ObjectUtils.isNotEmpty(userSession)) {
            return userSession;
        }
        return null;
    }
}
